package cn.epsilon3.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.epsilon3.constant.Base;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @description Redis工具类
 * @author: epsilon3
 * @date: 2023/9/6 22:46
 */
@Component
public class RedisUtils {

    private static RedisTemplate<String, Object> redisTemplate;

    /**
     * 私有化
     */
    private RedisUtils() {
    }

    /**
     * 实例化
     *
     * @return RedisUtils
     */
    public static RedisUtils in() {
        return new RedisUtils();
    }

    /**
     * 注入redis模板
     *
     * @param template RedisTemplate
     */
    @Autowired
    public void setRedisTemplate(RedisTemplate<String, Object> template) {
        redisTemplate = template;
    }

    /**
     * 设置有效时间
     *
     * @param key     Redis键
     * @param timeout 超时时间
     */
    public void expire(String key, Long timeout) {
        redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
    }

    /**
     * 设置对象缓存
     *
     * @param key   key
     * @param value obj
     */
    public RedisUtils setObj(String key, Object value) {
        opsForValue().set(key, value);
        return this;
    }

    /**
     * 获取对象缓存
     *
     * @param key key
     * @return obj
     */
    public Object getObj(String key) {
        return opsForValue().get(key);
    }

    /**
     * 获取对象缓存  String
     *
     * @param key key
     * @return obj
     */
    public String getObjAsStr(String key) {
        return String.valueOf(opsForValue().get(key));
    }

    /**
     * 获取对象缓存 Integer
     *
     * @param key key
     * @return obj
     */
    public Integer getObjAsInt(String key) {
        return Integer.valueOf(getObjAsStr(key));
    }

    /**
     * 获取对象缓存 Long
     *
     * @param key key
     * @return obj
     */
    public Long getObjAsLong(String key) {
        return Long.valueOf(getObjAsStr(key));
    }

    /**
     * 获取对象缓存 Double
     *
     * @param key key
     * @return obj
     */
    public Double getObjAsDouble(String key) {
        return Double.valueOf(getObjAsStr(key));
    }

    /**
     * 删除对象缓存
     *
     * @param key key
     */
    public void deleteObj(String key) {
        if (hasKey(key)) {
            redisTemplate.delete(key);
        }
    }

    /**
     * 设置List缓存
     *
     * @param key  key
     * @param list list
     * @return 列表长度
     */
    public <T> Long setList(String key, List<T> list) {
        Long length = redisTemplate.opsForList().rightPushAll(key, list);
        return ObjectUtil.isNull(length) ? 0 : length;
    }

    /**
     * 获取List缓存
     *
     * @param key key
     * @return list
     */
    public <T> List<T> getList(String key, Class<T> clazz) {
        return Objects.requireNonNull(redisTemplate.opsForList().range(key, Base.INT0, -1))
                .stream()
                .map(obj -> (T) obj)
                .collect(Collectors.toList());
    }


    /**
     * 是否存在缓存
     *
     * @param key key
     */
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 获取opsForValue
     *
     * @return ValueOperations<String, Object>
     */
    public ValueOperations<String, Object> opsForValue() {
        return redisTemplate.opsForValue();
    }
}
